#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define BUFFER_SIZE 5  // 缓冲区大小
int buffer[BUFFER_SIZE];
int in = 0, out = 0;  // 生产/消费位置索引

// 信号量定义
sem_t empty;  // 空位置数量（初始值=缓冲区大小）
sem_t full;   // 满位置数量（初始值=0）
sem_t mutex;  // 互斥锁（初始值=1）

// 生产者线程
void* producer(void* arg) {
    for (int i = 1; i <= 10; i++) {
        int data = i;
        
        // 等待空位置（P操作）
        sem_wait(&empty);
        // 获取互斥锁
        sem_wait(&mutex);
        
        // 放入数据
        buffer[in] = data;
        printf("生产: %d (位置: %d)\n", data, in);
        in = (in + 1) % BUFFER_SIZE;
        
        // 释放互斥锁
        sem_post(&mutex);
        // 增加满位置计数
        sem_post(&full);
        
        sleep(1);  // 模拟生产耗时
    }
    return NULL;
}

// 消费者线程
void* consumer(void* arg) {
    while (1) {
        // 等待满位置（P操作）
        sem_wait(&full);
        // 获取互斥锁
        sem_wait(&mutex);
        
        // 取出数据
        int data = buffer[out];
        printf("消费: %d (位置: %d)\n", data, out);
        out = (out + 1) % BUFFER_SIZE;
        
        // 释放互斥锁
        sem_post(&mutex);
        // 增加空位置计数
        sem_post(&empty);
        
        sleep(2);  // 模拟消费耗时
    }
    return NULL;
}

int main() {
    pthread_t prod_tid, cons_tid;
    
    // 初始化信号量
    sem_init(&empty, 0, BUFFER_SIZE);  // 初始空位置=缓冲区大小
    sem_init(&full, 0, 0);             // 初始满位置=0
    sem_init(&mutex, 0, 1);            // 互斥锁初始值=1
    
    // 创建线程
    pthread_create(&prod_tid, NULL, producer, NULL);
    pthread_create(&cons_tid, NULL, consumer, NULL);
    
    // 等待线程结束
    pthread_join(prod_tid, NULL);
    pthread_join(cons_tid, NULL);  // 实际运行时需手动终止
    
    // 销毁信号量
    sem_destroy(&empty);
    sem_destroy(&full);
    sem_destroy(&mutex);
    
    return 0;
}
